package com.dailyyoga.view;

import com.dailyyoga.engine.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

public class PullScrollView extends ScrollView {

	private static final float SCROLL_RATIO = 0.5f; // 阻尼系数,越小阻力就越大
	private static final int TURN_DISTANCE = 100; // 滑动至刷新的距离

	private State mState = State.NORMAL; // 状态

	private enum State {
		UP, // 顶部
		DOWN, // 低部
		NORMAL // 正常
	}

	private View mContentView; // Scroll View的

	private View mHeaderView; // 头部View
	// private int mHeaderHeight; // 头部View高度
	private int mHeaderVisibleHeight; // 头部View显示高度

	private OnRefreshListener mOnRefreshListener; // 状态改变监听
	private OnChanageListener mOnChanageListener; // 滑动监听

	private boolean isTop = false; // 　是否移动到顶部

	private float mTouchDownY; // 首次点击的Y坐标

	private int mInitTop, mInitBottom; // 头部图片初始的顶部和底部
	private int mCurrentTop, mCurrentBottom; // 头部图片拖动时顶部和底部

	private boolean mEnableTouch = false; // 是否关闭Scroll的滑动
	private boolean isMoving = false; // 是否开始移动

	private Rect mContentRect = new Rect(); // ScrollView的content view矩形

	// -----------构造方法------------//
	public PullScrollView(Context context) {
		super(context);
		init(context, null);
	}

	public PullScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	public PullScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context, attrs);
	}

	/**
	 * 初始化scroll
	 * 
	 * @param context
	 * @param attrs
	 */
	private void init(Context context, AttributeSet attrs) {
		setOverScrollMode(OVER_SCROLL_NEVER);
		if (attrs != null) {
			TypedArray ta = context.obtainStyledAttributes(attrs,
					R.styleable.PullScrollView);
			if (ta != null) {
				// mHeaderHeight = (int)
				// ta.getDimension(R.styleable.PullScrollView_headerHeight, -1);
				mHeaderVisibleHeight = (int) ta.getDimension(
						R.styleable.PullScrollView_headerVisibleHeight, -1);
				ta.recycle();
			}
		}
	}

	// -------------类方法-------------//
	/**
	 * 设置头部View
	 * 
	 * @param view
	 */
	public void setHeaderView(View view) {
		mHeaderView = view;
	}

	/**
	 * 设置监听
	 * 
	 * @param turnListener
	 */
	public void setOnRefreshListener(OnRefreshListener refreshListener) {
		mOnRefreshListener = refreshListener;
	}

	/**
	 * 设置监听
	 * 
	 * @param turnListener
	 */
	public void setOnChanageListener(OnChanageListener chanageListener) {
		mOnChanageListener = chanageListener;
	}

	/**
	 * 是否开启动画
	 * 
	 * @return
	 */
	private boolean isNeedAnimation() {
		return !mContentRect.isEmpty() && isMoving;
	}

	// --------------Override------------//

	@Override
	protected void onFinishInflate() {
		if (getChildCount() > 0) {
			mContentView = getChildAt(0);
		}
	}

	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		if (getScrollY() == 0) {
			isTop = true;
		}

		if (mOnChanageListener != null) {
			mOnChanageListener.onChanage();
		}

	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			mTouchDownY = ev.getY();
			mCurrentTop = mInitTop = mHeaderView.getTop();
			mCurrentBottom = mInitBottom = mHeaderView.getBottom();
		}
		return super.onInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		if (mContentView != null) {
			doTouchEvent(ev);
		}
		// 禁止空间自身的移动
		return mEnableTouch || super.onTouchEvent(ev);
	}

	/**
	 * 触摸时事件处理
	 * 
	 * @param ev
	 */
	private void doTouchEvent(MotionEvent event) {
		int action = event.getAction();

		switch (action) {
		case MotionEvent.ACTION_MOVE:
			doActionMove(event);
			break;
		case MotionEvent.ACTION_UP:
			// 回滚动画
			if (isNeedAnimation()) {
				rollBackAnimation();
			}

			if (getScrollY() == 0) {
				mState = State.NORMAL;
			}

			isMoving = false;
			mEnableTouch = false;
			break;
		default:
			break;
		}
	}

	/**
	 * 执行移动动画
	 * 
	 * @param event
	 */
	private void doActionMove(MotionEvent event) {
		// 当滚动到顶部时，将状态设置为正常，避免先向上拖动再向下拖动到顶端后首次触摸不响应的问题
		if (getScrollY() == 0) {
			mState = State.NORMAL;

			// 滑动经过顶部初始位置时，修正Touch down的坐标为当前Touch点的坐标
			if (isTop) {
				isTop = false;
				mTouchDownY = event.getY();
			}
		}

		float deltaY = event.getY() - mTouchDownY;

		// 对于首次Touch操作要判断方位：UP OR DOWN
		if (deltaY < 0 && mState == State.NORMAL) {
			mState = State.UP;
		} else if (deltaY > 0 && mState == State.NORMAL) {
			mState = State.DOWN;
		}

		if (mState == State.UP) {
			deltaY = deltaY < 0 ? deltaY : 0;

			isMoving = false;
			mEnableTouch = false;

		} else if (mState == State.DOWN) {
			if (getScrollY() <= deltaY) {
				mEnableTouch = true;
				isMoving = true;
			}
			deltaY = deltaY < 0 ? 0 : deltaY;
		}

		if (isMoving) {
			// 初始化content view矩形
			if (mContentRect.isEmpty()) {
				// 保存正常的布局位置
				mContentRect.set(mContentView.getLeft(), mContentView.getTop(),
						mContentView.getRight(), mContentView.getBottom());
			}

			// 计算header移动距离(手势移动的距离*阻尼系数*0.5)
			float headerMoveHeight = deltaY * 0.5f * SCROLL_RATIO;

			Log.d("move", "mInitTop=" + mInitTop + "  mInitBottom"
					+ mInitBottom + "**" + "mCurrentTop=" + mCurrentTop
					+ "  mCurrentBottom=" + mCurrentBottom);

			mCurrentTop = (int) (mInitTop + headerMoveHeight);
			mCurrentBottom = (int) (mInitBottom + headerMoveHeight);

			// 计算content移动距离(手势移动的距离*阻尼系数)
			float contentMoveHeight = deltaY * SCROLL_RATIO;

			// 修正content移动的距离，避免超过header的底边缘
			int headerBottom = mCurrentBottom - mHeaderVisibleHeight;
			int top = (int) (mContentRect.top + contentMoveHeight);
			int bottom = (int) (mContentRect.bottom + contentMoveHeight);

			if (top <= headerBottom) {
				// 移动content view
				mContentView.layout(mContentRect.left, top, mContentRect.right,
						bottom);

				// 移动header view
				mHeaderView.layout(mHeaderView.getLeft(), mCurrentTop,
						mHeaderView.getRight(), mCurrentBottom);
			}
		}
	}

	/**
	 * 回滚动画
	 */
	private void rollBackAnimation() {
		// header view动画
		TranslateAnimation tranAnim = new TranslateAnimation(0, 0,
				Math.abs(mInitTop - mCurrentTop), 0);
		tranAnim.setDuration(200);

		// content view动画
		TranslateAnimation innerAnim = new TranslateAnimation(0, 0,
				mContentView.getTop(), mContentRect.top);
		innerAnim.setDuration(200);

		// 开始动画
		mContentView.startAnimation(innerAnim);
		mHeaderView.startAnimation(tranAnim);

		// 设置最后的位置
		mHeaderView.layout(mHeaderView.getLeft(), mInitTop,
				mHeaderView.getRight(), mInitBottom);
		mContentView.layout(mContentRect.left, mContentRect.top,
				mContentRect.right, mContentRect.bottom);

		mContentRect.setEmpty();

		// 回调监听器
		if (mCurrentTop > mInitTop + TURN_DISTANCE
				&& mOnRefreshListener != null) {
			mOnRefreshListener.onRefresh();
		}
	}

	// -------------接口-----------//
	public interface OnRefreshListener {
		/**
		 * 刷新回调方法
		 */
		public void onRefresh();
	}

	public interface OnChanageListener {
		/**
		 * 刷新回调方法
		 */
		public void onChanage();
	}

}
